import { _decorator, Animation, Collider2D, Component, Contact2DType, Enum, EventTouch, Input, input, instantiate, Node, Prefab, v3, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

export enum ShootType {
    none,
    oneShoot,
    twoShoot
}
Enum(ShootType)

@ccclass('Player')
export class Player extends Component {

    //射击间隔
    @property
    shootRate: number = 0.3
    //子弹图层、子弹容器
    @property(Node)
    bulletList: Node = null

    //单发子弹模式模板
    @property(Prefab)
    bulletOnePrefab: Prefab = null
    //双发子弹模式模板
    @property(Prefab)
    bulletTwoPrefab = null

    //单发模式子弹生成器
    @property(Node)
    bulletOneGenerator: Node = null
    //双发模式子弹生成器（两个）（一号位/二号位）
    @property(Node)
    bulletTwoGenerator1: Node = null
    @property(Node)
    bulletTwoGenerator2: Node = null

    //射击模式状态
    @property({ type: ShootType })
    shootType: ShootType = ShootType.oneShoot
    //血量
    @property
    hp: number = 3

    //动画组件
    @property(Animation)
    anim: Animation = null

    //受伤后无敌时间
    @property
    invincibleTime: number = 1
    //是否为无敌状态
    @property
    isInvincible: boolean = false

    //初始化
    start(): void {
        //开始监听触摸事件
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this)
        //每隔固定时间发射一颗子弹
        this.schedule(this.shoot, this.shootRate)
    }

    //受伤后的一系列操作
    hit(n: number) {
        //如果生命已经归零结束方法
        if (this.hp <= 0) {
            return
        }
        //如果当前处于无敌状态结束方法
        if (this.isInvincible) {
            console.log('玩家当前处于无敌状态');
            return
        }
        //减生命值
        this.hp = this.hp - n
        //如果生命归零玩家坠毁并结束调用
        if (this.hp === 0) {
            console.log('玩家生命值归零');
            this.down()
            return
        }
        //排除以上情况判断玩家受伤
        console.log('玩家受伤了');
        //播放受伤动画
        this.anim.play('Player_Hit')
        //受伤以后触发一秒无敌
        this.invincible()
    }

    invincible() {
        console.log('进入无敌状态');
        this.isInvincible = true
        //定时器一秒无敌状态
        this.scheduleOnce(() => {
            console.log('无敌状态解除');
            //状态解除
            this.isInvincible = false
            //切换成默认待机动画
            this.anim.play()
        }, 1)
    }

    down() {
        //死亡停止继续射出子弹
        this.unschedule(this.shoot)
        //播放坠毁动画
        this.anim.play('Player_Down')
        //解绑监听
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this)
    }

    changeShootType(ST:ShootType){
        this.shootRate = 0.3
        this.shootType = ST
        this.unschedule(this.shoot)
        this.schedule(this.shoot, this.shootRate)
    }

    //玩家射击方法
    shoot() {
        //模式切换
        switch (this.shootType) {
            case ShootType.oneShoot:
                this.oneShoot()
                break;

            case ShootType.twoShoot:
                this.twoShoot()
                break;
        }

    }

    oneShoot() {
        //生成子弹模型
        const bullet = instantiate(this.bulletOnePrefab)
        //添加到指定子弹容器
        this.bulletList.addChild(bullet)
        //设置坐标到发射器位置
        bullet.setWorldPosition(this.bulletOneGenerator.worldPosition)
    }

    twoShoot() {
        //生成子弹模型
        const bullet1 = instantiate(this.bulletTwoPrefab)
        const bullet2 = instantiate(this.bulletTwoPrefab)
        //添加到子弹容器
        this.bulletList.addChild(bullet1)
        this.bulletList.addChild(bullet2)
        //设置坐标到发射器位置
        bullet1.setWorldPosition(this.bulletTwoGenerator1.worldPosition)
        bullet2.setWorldPosition(this.bulletTwoGenerator2.worldPosition)
    }

    onTouchMove(event: EventTouch) {
        //获取玩家位置
        const player = this.node.position
        //通过触摸位移计算玩家最终坐标
        let targetPosition = new Vec3(player.x + event.getDeltaX(), player.y + event.getDeltaY(), player.z)

        //限制玩家最终位置确保不出边界
        if (targetPosition.x > 230) {
            targetPosition.x = 230
        } else if (targetPosition.x < -230) {
            targetPosition.x = -230
        } else if (targetPosition.y > 360) {
            targetPosition.y = 360
        } else if (targetPosition.y < -360) {
            targetPosition.y = -360
        }

        //设置最终坐标
        this.node.setPosition(targetPosition)
    }
}


